---@class EventManager

EventManager = ClientFight.CreateClass("EventManager")
local this = EventManager
function FighterManager:ctor()

end
function this.getIns()
    return this;
end

function this.addEventListener(fight, eventId, fighterId, fightEventListener)
    ---@type table<number, table<number, table<string, IFightEventListener>>>
    local eventListeners = fight.eventListeners;

    local map = nil;
    if (not eventListeners[eventId]) then
        map = {};
        eventListeners[eventId] = map;
    else
        map = eventListeners[eventId];
    end

    local events = nil;
    if (not map[fighterId]) then
        events = {};
        map[fighterId] = events;
    else
        events = map[fighterId];
    end
    events[fightEventListener:getId()] = fightEventListener;
end

function this.removeEventListener(fight, eventId, fighterId, fightEventListenerId)
    ---@type table<number, table<number, table<string, IFightEventListener>>>
    local eventListeners = fight.eventListeners;
    if (not eventListeners[eventId]) then
        return ;
    end
    local map = eventListeners[eventId];
    if (not map[fighterId]) then
        return ;
    end
    local events = map[fighterId];
    events[fightEventListenerId] = nil;
end

function this.notifyEventListener(fight, eventId, fighterId, ...)
    ---@type table<number, table<number, table<string, IFightEventListener>>>
    local eventListeners = fight.eventListeners;
    if (not eventListeners[eventId]) then
        return ;
    end
    local map = eventListeners[eventId];
    if (not map[fighterId]) then
        return ;
    end
    local eventsMap = map[fighterId];

    local events = {};
    addTable(events, eventsMap);
    this.sort(events)
    for i, fightEventListener in pairs(events) do


        fightEventListener:notify(eventId, ...);

    end
end

function this.sort(events)
    if (events == nil or table.getn(events) < 2) then
        return ;
    end
    table.sort(events,function(o1, o2)
        return o2:priority() > o1:priority();
    end);
    --		BubbleSortUtil.bubble(events, new Comparator<IFightEventListener>() {
    --			@Override
    --			public int compare(IFightEventListener o1, IFightEventListener o2) {
    --				return o2.priority() - o1.priority();
    --			}
    --		});
end

function this.addDelayedEvent(fight, frame, event)
    local list = {};
    if (fight.events[frame]) then
        list = fight.events[frame];
    else
        list = {};
        fight.events[frame] = list;
    end
    table.insert(list, event);
end
